<?php

namespace app\controllers;

use app\components\LoginStateComponent;
use app\models\ChangePasswordForm;
use app\models\ForgetPasswordForm;
use app\models\LoginForm;
use app\models\RegistrationForm;
use Yii;
use yii\base\InvalidParamException;
use yii\helpers\Html;
use yii\web\Controller;
use yii\web\HttpException;
use yii\web\Response;
use yii\filters\VerbFilter;
use yii\web\Session;
use \yii\web\Request;

class SiteController extends Controller
{
    /**
     * @var Request $request
     */
    public $request = '';

    /**
     * @var Session $session
     */
    public $session;
    /**
     * @var string $sessionId
     */
    public $sessionId;

    /**
     * @var LoginStateComponent $loginState
     */
    public $loginState;

    public $enableCsrfValidation = false;

    public static $deviceConfig = [
        'workModel' => [
            0 => '分段定时模式',
            1 => '智能抽油模式',
            2 => '远程手动模式',
        ],
        'switch' => [
            1 => '开',
            0 => '关'
        ]
    ];

    public function init()
    {
        parent::init();
        $this->request = Yii::$app->request;
        $this->session = Yii::$app->session;
        $this->loginState = Yii::$app->loginState;
        $this->session->open();
        Yii::warning('session id:' . $this->sessionId);
        $this->sessionId = $this->session->getId();
        Yii::$app->language = 'zh-CN';
    }

    /**
     * @inheritdoc
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }

    /**
     * Displays homepage.
     *
     * @return string
     */
    public function actionIndex()
    {
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'pageIndex' => '1',
            'pageSize' => '10'
        ];
        $deviceList = Yii::$app->util->postJson('/getDeviceList', $params);
        if (isset($deviceList['returnCode']) && $deviceList['returnCode'] === '4003') {
            if (!\Yii::$app->request->isAjax) {
                \Yii::$app->controller->redirect('/site/login');
            }
        } else {
            $list = $deviceList['data']['devices'];
            return $this->render('index', [
                'list' => $list
            ]);
        }

    }

    public function actionInfo()
    {
        $deviceId = $this->request->get('deviceId');
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#GET#STATUS#0#12*'
        ];
        $deviceInfo = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if (isset($deviceInfo['returnCode']) && $deviceInfo['returnCode'] === '4003') {
            if (!\Yii::$app->request->isAjax) {
                \Yii::$app->controller->redirect('/site/login');
            }
        } elseif ($deviceInfo['returnCode'] !== '200') {
            return $this->render('error', [
                'message' => $deviceInfo['message'],
                'name' => '设备信息',
            ]);
        } else {
            $deviceData = $this->parseOperationResult($deviceInfo['data']['operationResult']);
            return $this->render('info', [
                'deviceInfo' => $deviceData
            ]);
        }
    }

    public function actionDelDevice()
    {
        $deviceId = $this->request->get('deviceId');
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
        ];
        $deviceInfo = Yii::$app->util->postJson('/deleteDevice', $params, true, false);
        if ($deviceInfo['returnCode'] != '200') {
            $this->renderJson($deviceInfo['returnCode'], $deviceInfo['message']);
        } else {
            $this->renderJson(1, '删除成功');
        }
    }

    public function actionAddDevice()
    {
        $deviceId = $this->request->post('deviceId');
        $deviceName = $this->request->post('deviceName');
        if (empty($deviceId) || empty($deviceName)) {
            throw  new InvalidParamException('参数错误');
        }
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'deviceName' => $deviceName,
        ];
        $deviceInfo = Yii::$app->util->postJson('/addDevice', $params, true, false);
        if ($deviceInfo['returnCode'] != '200') {
            $this->renderJson($deviceInfo['returnCode'], $deviceInfo['message']);
        } else {
            $this->renderJson(1, '设备添加成功');
        }
    }

    /**
     * 设置工作模式
     */
    public function actionSetWorkModel($deviceId)
    {
        $val = $this->request->post('val');
        if (!in_array($val, [0, 1, 2])) {
            throw  new InvalidParamException('参数错误');
        }
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#SET#MODE#' . $val . '#12*'
        ];
        $deviceInfo = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if ($deviceInfo['returnCode'] != '200') {
            $this->renderJson($deviceInfo['returnCode'], $deviceInfo['message']);
        } else {
            $this->renderJson(1, $deviceInfo['message']);
        }
    }

    private function renderJson($status, $message = '设置成功', $data = [])
    {
        echo json_encode([
            'status' => $status,
            'data' => $data,
            'message' => $message
        ]);
        exit();
    }

    /**
     * 启动设备
     */
    public function actionStartDevice($deviceId)
    {
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#SET#START#1#12*'
        ];
        $deviceInfo = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if ($deviceInfo['returnCode'] != '200') {
            $this->renderJson($deviceInfo['returnCode'], $deviceInfo['message']);
        } else {
            $this->renderJson(1, '设备启动成功');
        }
    }

    /**
     * 停止设备
     */
    public function actionStopDevice($deviceId)
    {
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#SET#SHUT#1#12*'
        ];
        $deviceInfo = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if ($deviceInfo['returnCode'] != '200') {
            $this->renderJson($deviceInfo['returnCode'], $deviceInfo['message']);
        } else {
            $this->renderJson(1, '设备停止成功');
        }
    }

    /**
     * 设置定时器
     */
    public function actionSetDeviceParam()
    {
        $deviceId = $this->request->get('deviceId');
        $duration1Data = self::concatHourMinutes($this->request->post('one'));
        $duration2Data = self::concatHourMinutes($this->request->post('two'));
        $duration3Data = self::concatHourMinutes($this->request->post('three'));
        $duration4Data = self::concatHourMinutes($this->request->post('four'));
        $duration5Data = self::concatHourMinutes($this->request->post('five'));
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#SET#TIMING#' . $duration1Data . '/' . $duration2Data .
                '/' . $duration3Data . '/' . $duration4Data . '/' . $duration5Data . '#12*'
        ];
        $deviceInfo = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if ($deviceInfo['returnCode'] != '200') {
            $this->renderJson($deviceInfo['returnCode'], $deviceInfo['message']);
        } else {
            $this->renderJson(1);
        }
    }

    private static function concatHourMinutes($data)
    {
        $start = self::parseTime($data[0]);
        $end = self::parseTime($data[1]);
        $startHour = str_pad($start[0], 2, '0', STR_PAD_LEFT);
        $startMinutes = str_pad($start[1], 2, '0', STR_PAD_LEFT);
        $endHour = str_pad($end[0], 2, '0', STR_PAD_LEFT);
        $endMinutes = str_pad($end[1], 2, '0', STR_PAD_LEFT);
        return $startHour . $startMinutes . $endHour . $endMinutes;
    }

    private static function parseTime($str)
    {
        $data = preg_match_all('/[0-9]+/', $str, $matches);
        return $matches[0];
    }

    private function parseOperationResult($binary)
    {
        $origin = $binary;
        $binary = preg_replace('/\$PHKJ#.*#GET#STATUS#/', '', $binary);
        $spiltData = explode('/', $binary);
        $workData = $spiltData[0];
        $trafficData = $spiltData[1];
        $duration1 = $spiltData[2];
        $duration2 = $spiltData[3];
        $duration3 = $spiltData[4];
        $duration4 = $spiltData[5];
        $duration5 = $spiltData[6];
        $total = substr($binary, strpos($binary, '#') + 1);
        $total = substr($total, strpos($total, '#') + 1);
        $total_detail = explode('#', $total);
        $data = [
            'config' => self::$deviceConfig,
            'origin' => $origin,
            'total' => [
                'onlineDuration' => $total_detail[0],
                'openTimes' => $total_detail[1],
            ],
            'workData' => [
                'origin' => $workData,
                'model' => substr($workData, 0, 1),
                'model_desc' => self::$deviceConfig['workModel'][substr($workData, 0, 1)],
                'switch1' => substr($workData, 1, 1),
                'switch1_desc' => self::$deviceConfig['switch'][substr($workData, 1, 1)],
                'switch2' => substr($workData, 2, 1),
                'switch2_desc' => self::$deviceConfig['switch'][substr($workData, 2, 1)],
                'switch3' => substr($workData, 3, 1),
                'switch3_desc' => self::$deviceConfig['switch'][substr($workData, 3, 1)],
            ],
            'trafficData' => [
                'origin' => $trafficData,
                'traffic1' => substr($trafficData, 0, 2),
                'traffic1Upper' => substr($trafficData, 2, 2),
                'traffic1Lower' => substr($trafficData, 4, 2),
                'traffic1Rate' => substr($trafficData, 6, 2),
                'traffic2' => substr($trafficData, 8, 2),
                'traffic2Upper' => substr($trafficData, 10, 2),
                'traffic2Lower' => substr($trafficData, 12, 2),
                'traffic2Rate' => substr($trafficData, 14, 2),
            ],
            'duration' => [
                [
                    substr($duration1, 0, 2),
                    substr($duration1, 2, 2),
                    substr($duration1, 4, 2),
                    substr($duration1, 6, 2),
                ],
                [
                    substr($duration2, 0, 2),
                    substr($duration2, 2, 2),
                    substr($duration2, 4, 2),
                    substr($duration2, 6, 2),
                ],
                [
                    substr($duration3, 0, 2),
                    substr($duration3, 2, 2),
                    substr($duration3, 4, 2),
                    substr($duration3, 6, 2),
                ],
                [
                    substr($duration4, 0, 2),
                    substr($duration4, 2, 2),
                    substr($duration4, 4, 2),
                    substr($duration4, 6, 2),
                ],
                [
                    substr($duration5, 0, 2),
                    substr($duration5, 2, 2),
                    substr($duration5, 4, 2),
                    substr($duration5, 6, 2),
                ]
            ]
        ];
        foreach ($data['duration'] as &$item) {
            $start = $item[0] . '点' . $item[1] . '分';
            $end = $item[2] . '点' . $item[3] . '分';
            array_unshift($item, $end);
            array_unshift($item, $start);
        }
        return $data;
    }

    /**
     * 获取设备时间
     */
    function actionGetClock($deviceId)
    {
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#GET#TIME#0#12*'
        ];
        $clockInfo = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if ($clockInfo['returnCode'] != '200') {
            throw new HttpException();
        }
        $time = $clockInfo['data']['operationResult'];
        $time = preg_replace('/\$PHKJ#.*#GET#TIME#/', '', $time);
        $time = str_replace('#12*', '', $time);
        $date = substr($time, 0, 4) . '年' . substr($time, 4, 2) . '月' . substr($time, 6, 2) . '日' .
            substr($time, 8, 2) . ':' . substr($time, 10, 2) . ':' . substr($time, 12, 2);
        echo json_encode(['time' => $date]);
    }

    /**
     * 设置设备时间
     * @param $deviceId
     * @throws HttpException
     */
    public function actionSetClock($deviceId)
    {
        $date = $this->request->post('date');
        if (empty($date)) {
            throw new InvalidParamException();
        }
        $date = preg_replace("/[^0-9]/", "", $date);
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#SET#TIME#' . $date . '#12*'
        ];
        $data = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if ($data['returnCode'] != '200') {
            $this->renderJson($data['returnCode'], $data['message']);
        } else {
            $this->renderJson(1);
        }
    }

    /**
     *
     */
    public function actionSetAd($deviceId)
    {
        $upper = $this->request->post('upper');
        $lower = $this->request->post('lower');
        $rate = $this->request->post('rate');
        if (strlen($upper) === 0 || strlen($lower) === 0 || strlen($rate) === 0) {
            throw new InvalidParamException();
        }
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
            'deviceId' => $deviceId,
            'operations' => '$PHKJ#IMEI#SET#ADBOUND#' . '1' . $upper . $lower . $rate . '#12*'
        ];
        $data = Yii::$app->util->postJson('/operateDevice', $params, true, true);
        if ($data['returnCode'] != '200') {
            $this->renderJson($data['returnCode'], $data['message']);
        } else {
            $this->renderJson(1);
        }
    }

    /**
     * Login action.
     *
     * @return Response|string
     */
    public function actionLogin()
    {
        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->redirect('/site/index');
        }
        return $this->render('login', [
            'model' => $model,
        ]);
    }

    /**
     * 修改密码
     *
     * @return Response|string
     */
    public function actionChangePassword()
    {
        $model = new ChangePasswordForm();
        if ($model->load(\Yii::$app->request->post()) && $model->changePassword()) {
            return $this->render('/message', [
                'title' => '修改密码成功',
                'message' => [
                    'type' => 'success',
                    'body' => '密码修改成功，' . Html::a('去重新登录', '/site/login')
                ]
            ]);
        }
        return $this->render('change_password', [
            'model' => $model,
        ]);
    }

    /**
     * 修改密码
     *
     * @return Response|string
     */
    public function actionForget()
    {
        $model = new ForgetPasswordForm();
        $model->setScenario('step1');
        if ($model->load(\Yii::$app->request->post()) && $model->checkMsg()) {
            $this->redirect('/site/forget-step2?mobile=' . $model->mobile);
        }
        return $this->render('forget_password_step1', [
            'model' => $model,
        ]);
    }

    /**
     * 修改密码
     *
     * @return Response|string
     */
    public function actionForgetStep2()
    {
        $mobile = $_GET['mobile'];
        $model = new ForgetPasswordForm();
        $model->setScenario('step2');
        if ($model->load(\Yii::$app->request->post()) && $model->changePassWord($mobile)) {
            return $this->render('/message', [
                'title' => '密码重置成功',
                'message' => [
                    'type' => 'success',
                    'body' => '密码重置成功，' . Html::a('去重新登录', '/site/login')
                ]
            ]);
        }
        return $this->render('forget_password_step2', [
            'model' => $model,
        ]);
    }

    /**
     * Displays the registration page.
     * After successful registration if enableConfirmation is enabled shows info message otherwise
     * redirects to home page.
     *
     * @return string
     * @throws \yii\web\HttpException
     */
    public function actionRegister()
    {

        /** @var RegistrationForm $model */
        $model = new RegistrationForm();
        if ($model->load(\Yii::$app->request->post()) && $model->register()) {
            return $this->render('/message', [
                'title' => '注册成功',
                'message' => [
                    'type' => 'success',
                    'body' => '你已成功注册账号：' . $model->username . ',' . Html::a('去登录', '/site/login')
                ]
            ]);
        }
        return $this->render('register', [
            'model' => $model,
            'module' => $this->module,
        ]);
    }

    public function actionSendMsg()
    {
        $mobile = $this->request->post('mobile');
        $type = $this->request->post('type');
        $params = [
            'mobile' => $mobile,
            'type' => $type,
        ];
        $data = Yii::$app->util->postJson('/sendMsg', $params, false);
        if ($data['returnCode'] != '200') {
            $this->renderJson($data['returnCode'], $data['message']);
        } else {
            $this->renderJson(1);
        }
    }

    /**
     * 退出登录
     * @throws HttpException
     */
    public function actionLogout()
    {
        $params = [
            'userId' => $this->loginState->getState('userId'),
            'sessionId' => $this->loginState->getState('sessionId'),
        ];
        $result = Yii::$app->util->postJson('/loginOut', $params);
        if ($result['returnCode'] !== '200') {
            throw new HttpException(-1, '接口异常！');
        }
        $this->loginState->clearSession();
        $this->redirect('/site/login');
    }
}
